package org.ainlolcat.ainscience.UI;

import org.ainlolcat.ainscience.Controller;
import org.ainlolcat.ainscience.column.Column;
import org.ainlolcat.ainscience.column.threshold.Threshold;
import org.ainlolcat.ainscience.entity.Entity;
import org.ainlolcat.ainscience.entity.EntityTableModel;
import org.ainlolcat.ainscience.entity.UnsupportedEntityTypeException;
import org.ainlolcat.ainscience.statistics.StaticticsTableModel;
import org.ainlolcat.ainscience.statistics.StatisticHandler;
import org.ainlolcat.ainscience.statistics.StatisticsCollectorImpl;
import org.ainlolcat.ainscience.tools;
import org.apache.log4j.Logger;
import org.math.plot.Plot2DPanel;

import javax.swing.*;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;

/**
 * @author ainlolcat
 * Date: 10/30/11
 */
public class SimpleEntityPanel extends JPanel{
    private static Logger log = Logger.getLogger(SimpleEntityPanel.class);
    Entity entity;
    JTable table;
    JToolBar toolbar;
    private class StatisticsWindow extends JFrame{
        JTable statistic;
        JPanel statRender;
        public StatisticsWindow(){
            super("Statistics");
            setSize(tools.getScreenSize().width/2,tools.getScreenSize().height/2);
            setLocation(0,0);
            setLayout(new GridLayout(0,2));
        }
        public void raise(){
            try{
                statistic = new JTable();
                statistic.setModel(new StaticticsTableModel(entity));
                statistic.addMouseListener(new MouseAdapter() {
                    @Override
                    public void mouseClicked(MouseEvent e) {
                        int row = statistic.getSelectedRow();
                        String name = (String) statistic.getValueAt(row,0);
                        StatisticHandler sh = new StatisticsCollectorImpl(entity).getHandler(name);
                        replaceStatRenderer(sh.getRenderer());
                    }
                });
                JScrollPane scroll = new JScrollPane(statistic);
                scroll.setLayout(new ScrollPaneLayout());
                add(scroll);
                setVisible(true);
            }catch(Exception e){
                e.printStackTrace();
                JOptionPane.showMessageDialog(null,"Sorry. Cannot gain statistic. Error: "+e.getLocalizedMessage());
            }
        }

        private void replaceStatRenderer(JPanel renderer){
            if (statRender!=null){
                remove(statRender);
            }
            statRender = renderer;
            add(renderer);
            setVisible(true);
        }
    }
    public SimpleEntityPanel(Entity entity){
        super(new BorderLayout(5,5));
        this.entity = entity;
        initToolbar();
        initTableView();
    }

    private void initTableView(){
        if (table != null)
            remove(table);
        table = new JTable(new EntityTableModel(entity))
        {
            @Override
            public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
                Component temp = super.prepareRenderer(renderer, row, column);
                if (!isCellSelected(row, column))
                    temp.setBackground(Color.WHITE);

                Column c = entity.getColumnByOrder(column);
                boolean critical = false;
                boolean warning = false;
                try{
                    if (c.getThresholds() != null)
                        for (Threshold t: c.getThresholds()){
                            if (t.isExceed(entity, column, row)){
                                if (t.getType() == Threshold.WARRNING)
                                    warning = true;
                                else
                                    critical = true;
                            }
                        }
                }catch (Exception e){
                    log.error(e);
                }
                if (warning)
                    temp.setBackground(Color.YELLOW);
                if (critical)
                    temp.setBackground(Color.RED);

                return temp;
            }
        };
        add(new JScrollPane(table), BorderLayout.CENTER);
    }

    private void initToolbar(){
        toolbar = new JToolBar();
        JButton reload = new JButton("Refresh");
        reload.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                initTableView();
            }
        });
        toolbar.add(reload);
        JButton plotLineSelected = new JButton("Plot line");
        plotLineSelected.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                int columnNum = table.getSelectedColumn();
                Column cy = entity.getColumnByOrder(columnNum);
                Column cx = entity.getXColumn(cy.getAxis());
                // define your data
                if (cy != null && cx != null && cx.isNumeric() && cy.isNumeric()) {
                    double[] x = cx.getDoubleRepresentation();
                    double[] y = cy.getDoubleRepresentation();
                    if (x.length != y.length) {
                        int len = x.length > y.length ? y.length : x.length;
                        x = Arrays.copyOf(x, len);
                        y = Arrays.copyOf(y, len);
                    }
                    Plot2DPanel plot = new Plot2DPanel();
                    plot.addLinePlot(cy.getName() + " by " + cx.getName(), x, y);
                    JFrame frame = new JFrame(cy.getName() + " by " + cx.getName());
                    frame.setSize(600, 600);
                    frame.setContentPane(plot);
                    frame.setVisible(true);
                } else if (cy != null && cy.isNumeric()) {
                    double[] y = cy.getDoubleRepresentation();
                    Plot2DPanel plot = new Plot2DPanel();
                    plot.addLinePlot(cy.getName(), y);
                    JFrame frame = new JFrame(cy.getName());
                    frame.setSize(600, 600);
                    frame.setContentPane(plot);
                    frame.setVisible(true);
                }
            }
        });
        toolbar.add(plotLineSelected);
        JButton plotScatterSelected = new JButton("Plot scatter");
        plotScatterSelected.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                int columnNum = table.getSelectedColumn();
                Column cy = entity.getColumnByOrder(columnNum);
                Column cx = entity.getXColumn(cy.getAxis());
                // define your data
                if (cy != null && cx != null && cx.isNumeric() && cy.isNumeric()) {
                    double[] x = cx.getDoubleRepresentation();
                    double[] y = cy.getDoubleRepresentation();
                    if (x.length != y.length) {
                        int len = x.length > y.length ? y.length : x.length;
                        x = Arrays.copyOf(x, len);
                        y = Arrays.copyOf(y, len);
                    }
                    Plot2DPanel plot = new Plot2DPanel();
                    plot.addScatterPlot(cy.getName() + " by " + cx.getName(), x, y);
                    JFrame frame = new JFrame(cy.getName() + " by " + cx.getName());
                    frame.setSize(600, 600);
                    frame.setContentPane(plot);
                    frame.setVisible(true);
                } else if (cy != null && cy.isNumeric()) {
                    double[] y = cy.getDoubleRepresentation();
                    Plot2DPanel plot = new Plot2DPanel();
                    plot.addScatterPlot(cy.getName(), y);
                    JFrame frame = new JFrame(cy.getName());
                    frame.setSize(600, 600);
                    frame.setContentPane(plot);
                    frame.setVisible(true);
                }
            }
        });
        toolbar.add(plotScatterSelected);

        JButton showStatistic = new JButton("Statistics");
        showStatistic.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                StatisticsWindow stat = new StatisticsWindow();
                stat.raise();
            }
        });
        toolbar.add(showStatistic);

        JButton export2excel = new JButton("Export");
        export2excel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                JFileChooser fc = new JFileChooser();
                fc.setCurrentDirectory(new File(Controller.getInstance().getProject().getHomeDir()));
                fc.showSaveDialog(null);
                File file = fc.getSelectedFile();
                if (file == null) return;
                try {
                    String filename = file.getCanonicalPath();
                    if (!filename.endsWith("xls"))
                        filename = filename + ".xls";
                    new ExcelStatisticsExporter().export(entity, filename);
                } catch (IOException e1) {
                    e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                }
            }
        });
        toolbar.add(export2excel);

        add(toolbar, BorderLayout.PAGE_START);
    }
}
